package cn.mengfly.testnrz.im.codec;

import cn.mengfly.testnrz.im.ProtoMsg;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * 自定义protobuf解码器
 *
 * @author Mengfly
 */
public class ProtobufDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        in.markReaderIndex();
        if (in.readableBytes() < 2) {
            // 不够包头
            return;
        }

        int length = in.readShort();
        if (length < 0) {
            // 非法连接，关闭
            ctx.close();
        }

        if (length > in.readableBytes()) {
            // 如果传输过来的消息体商都小于获取到的长度，重置读取位置
            in.resetReaderIndex();
            return;
        }

        // TODO 忽略： 读取魔数，版本号等其他信息
        // ...
        byte[] array;
        if (in.hasArray()) {
            // 堆缓冲
            ByteBuf slice = in.slice();
            array = slice.array();
        } else {
            // 直接缓冲
            array = new byte[length];
            in.readBytes(array, 0, length);
        }
        ProtoMsg.Message outMsg = ProtoMsg.Message.parseFrom(array);
        // 字节转成Protobuf的POJO对象
        if (outMsg != null) {
            out.add(outMsg);
        }
    }
}
